const express = require("express");
const router = express.Router();
const jwt = require("jsonwebtoken");
const db = require("../config/database");
const { createDocumentedRoute } = require("../utils/routeDecorator");
const crypto = require('crypto');
const https = require('https');
const { Logger } = require('../utils/logger');

router.post("/login", async (req, res) => {
  try {
    const { phone, password, role } = req.body;

    // 验证角色参数（如果传入）
    const validRoles = ['user', 'admin'];
    if (role && !validRoles.includes(role)) {
      return res.status(400).json({
        code: 400,
        message: "当前账号异常，无法进入系统"
      });
    }

    // 查询用户 - 如果没有传入role，则不包含role条件
    let rows;
    if (role) {
      [rows] = await db.execute(
        "SELECT * FROM user WHERE phone = ? AND role = ?",
        [phone, role]
      );
    } else {
      [rows] = await db.execute(
        "SELECT * FROM user WHERE phone = ?",
        [phone]
      );
    }
    const user = rows[0];
    if (!user) {
      return res.status(401).json({
        code: 401,
        message: "手机号或密码错误",
      });
    }

    // 验证密码
    if (user.password !== password) {
      return res.status(401).json({
        code: 401,
        message: "手机号或密码错误",
      });
    }

    // 生成 JWT token
    const token = jwt.sign(
      { id: user.id, nickname: user.nickname, phone: user.phone },
      "your-secret-key",
      {
        expiresIn: "1000d",
      }
    );

    res.json({
      code: 200,
      message: "登录成功",
      data: {
        token,
        user: {
          id: user.id,
          nickname: user.nickname,
          phone: user.phone,
          role: user.role,
          status: user.status,
          idCard: user.idCard,
          realName: user.realName,
        },
      },
    });
  } catch (error) {
    console.error("登录错误:", error);
    res.status(500).json({
      code: 500,
      message: "服务器内部错误",
      error: error.message,
    });
  }
});

router.post("/register", async (req, res) => {
  try {
    const { password, phone } = req.body;

    // 检查用户是否已存在
    const [existingUsers] = await db.execute(
      "SELECT id FROM user WHERE phone = ?",
      [phone]
    );
    if (existingUsers.length > 0) {
      return res.status(400).json({
        code: 400,
        message: "手机号已存在",
      });
    }

    // 获取当前最大用户ID，确保从100000开始
    const [maxIdResult] = await db.execute(
      "SELECT MAX(id) as maxId FROM user"
    );
    const nextId = Math.max(100000, (maxIdResult[0].maxId || 0) + 1);
    const nickname = phone

    // 注册成功插入数据库
    const sql = "INSERT INTO user (id, nickname, password, phone) VALUES (?, ?, ?, ?)";
    const [result] = await db.execute(sql, [nextId, nickname, password, phone]);

    // 注册成功
    res.json({
      code: 200,
      message: "注册成功",
      data: {
        id: nextId,
        nickname,
        phone,
      },
    });
  } catch (err) {
    console.error("注册失败:", err);
    return res.status(500).json({
      code: 500,
      message: "注册失败",
      error: err.message,
    });
  }
});

router.post("/setProfile", async (req, res) => {
  try {
    const { idCard, realName, phone, address } = req.body;
    
    // 验证必填字段
    if (!idCard || !realName || !phone) {
      return res.status(400).json({
        code: 400,
        message: "身份证号、真实姓名和手机号为必填项"
      });
    }
    
    // 获取并验证token
    const token = req.headers.authorization?.replace('Bearer ', '');
    if (!token) {
      return res.status(401).json({
        code: 401,
        message: "未登录"
      });
    }
    
    let decoded;
    try {
      decoded = jwt.verify(token, process.env.JWT_SECRET || "your-secret-key");
    } catch (error) {
      return res.status(401).json({
        code: 401,
        message: "无效的token"
      });
    }
        // 检查身份证号是否已被其他用户绑定
    const [idCardCheck] = await db.execute(
      "SELECT id FROM user WHERE idCard = ? AND id != ?",
      [idCard, decoded.id]
    );
    if (idCardCheck.length > 0) {
      return res.status(200).json({
        code: 400,
        message: "该身份证号已被其他账号绑定"
      });
    }
    
    // 检查手机号是否已被其他用户绑定
    const [phoneCheck] = await db.execute(
      "SELECT id FROM user WHERE phone = ? AND id != ?",
      [phone, decoded.id]
    );
    if (phoneCheck.length > 0) {
      return res.status(200).json({
        code: 400,
        message: "该手机号已被其他账号绑定"
      });
    }
    // 调用腾讯云身份验证服务
    const verificationResult = await verifyIdentity(realName, idCard);
    if (!verificationResult.success) {
      return res.status(200).json({
        code: 400,
        message: verificationResult.message || "身份验证失败"
      });
    }
    // 更新用户信息
    const sql = "UPDATE user SET idCard = ?, realName = ?, phone = ?, address = ?, status = 3 WHERE id = ?";
    const [result] = await db.execute(sql, [idCard, realName, phone, address, decoded.id]);
    
    if (result.affectedRows === 0) {
      return res.status(404).json({
        code: 404,
        message: "用户不存在"
      });
    }
    
    res.json({
      code: 200,
      data: {
        id: decoded.id,
        idCard: idCard.replace(/(\d{6})\d{8}(\d{4})/, '$1********$2'),
        realName,
        phone: phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2'),
        address,
        status: 3
      },
      message: "更新用户信息成功"
    });
    
  } catch (error) {
    console.error('更新用户信息失败:', error);
    res.status(500).json({
      code: 500,
      message: "服务器内部错误"
    });
  }
});

const verifyIdentity = async (name, idCard) => {
  try {
    // 导入正确的身份验证模块
    const FaceidClient = require('tencentcloud-sdk-nodejs').faceid.v20180301.Client;
    
    // 实例化身份验证客户端
    const client = new FaceidClient({
      credential: {
        secretId: process.env.TENCENT_SECRET_ID,
        secretKey: process.env.TENCENT_SECRET_KEY
      },
      region: process.env.TENCENT_REGION || "ap-beijing",
      profile: {
        signMethod: "TC3-HMAC-SHA256",
        httpProfile: {
          reqMethod: "POST",
          reqTimeout: 30
        }
      }
    });
    
    // 调用身份证验证接口
    const params = {
      IdCard: idCard,
      Name: name
    };
    
    const data = await client.IdCardVerification(params);
    
    // 检查验证结果
    if (data.Result === "0") {
      return {
        success: true,
        message: "身份验证成功",
        data: data
      };
    } else {
      return {
        success: false,
        message: "身份信息不匹配，请检查姓名和身份证号",
        code: data.Result
      };
    }
    
  } catch (error) {
    console.error('身份验证服务调用失败:', error);
    
    // 如果是网络错误或服务不可用，可以选择跳过验证（根据业务需求）
    if (process.env.NODE_ENV === 'development') {
      console.warn('开发环境跳过身份验证');
      return {
        success: true,
        message: "开发环境跳过身份验证"
      };
    }
    
    return {
      success: false,
      message: "身份验证服务暂时不可用，请稍后重试"
    };
  }
};

// 微信配置
const wechatConfig = {
  appId: process.env.WECHAT_APP_ID || 'your_app_id',
  appSecret: process.env.WECHAT_APP_SECRET || 'your_app_secret'
};

// 缓存access_token和jsapi_ticket
let tokenCache = {
  access_token: null,
  access_token_expires: 0,
  jsapi_ticket: null,
  jsapi_ticket_expires: 0
};

// 获取微信access_token
const getAccessToken = async () => {
  try {
    // 检查缓存是否有效
    if (tokenCache.access_token && Date.now() < tokenCache.access_token_expires) {
      return tokenCache.access_token;
    }

    const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${wechatConfig.appId}&secret=${wechatConfig.appSecret}`;
    
    return new Promise((resolve, reject) => {
      https.get(url, (res) => {
        let data = '';
        res.on('data', (chunk) => {
          data += chunk;
        });
        res.on('end', () => {
          try {
            const result = JSON.parse(data);
            if (result.access_token) {
              // 缓存token，提前5分钟过期
              tokenCache.access_token = result.access_token;
              tokenCache.access_token_expires = Date.now() + (result.expires_in - 300) * 1000;
              resolve(result.access_token);
            } else {
              reject(new Error(result.errmsg || '获取access_token失败'));
            }
          } catch (error) {
            reject(error);
          }
        });
      }).on('error', reject);
    });
  } catch (error) {
    Logger.logError('获取access_token失败:', error);
    throw error;
  }
};

// 获取jsapi_ticket
const getJsapiTicket = async () => {
  try {
    // 检查缓存是否有效
    if (tokenCache.jsapi_ticket && Date.now() < tokenCache.jsapi_ticket_expires) {
      return tokenCache.jsapi_ticket;
    }

    const accessToken = await getAccessToken();
    const url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${accessToken}&type=jsapi`;
    
    return new Promise((resolve, reject) => {
      https.get(url, (res) => {
        let data = '';
        res.on('data', (chunk) => {
          data += chunk;
        });
        res.on('end', () => {
          try {
            const result = JSON.parse(data);
            if (result.ticket) {
              // 缓存ticket，提前5分钟过期
              tokenCache.jsapi_ticket = result.ticket;
              tokenCache.jsapi_ticket_expires = Date.now() + (result.expires_in - 300) * 1000;
              resolve(result.ticket);
            } else {
              reject(new Error(result.errmsg || '获取jsapi_ticket失败'));
            }
          } catch (error) {
            reject(error);
          }
        });
      }).on('error', reject);
    });
  } catch (error) {
    throw error;
  }
};

// 生成随机字符串
const generateNonceStr = () => {
  return Math.random().toString(36).substr(2, 15);
};

// 生成时间戳
const generateTimestamp = () => {
  return parseInt(Date.now() / 1000).toString();
};

// 生成微信JS-SDK签名
const generateSignature = (ticket, nonceStr, timestamp, url) => {
  const string = `jsapi_ticket=${ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`;
  console.log('string1', string);
  return crypto.createHash('sha1').update(string).digest('hex');
};

/**
 * @swagger
 * /api/auth/wechat/signature:
 *   post:
 *     summary: 获取微信分享签名
 *     tags: [Auth]
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - url
 *             properties:
 *               url:
 *                 type: string
 *                 description: 当前页面URL（不包含#及其后面部分），必须与微信安全域名完全匹配
 *                 example: "https://www.stellargang.cn/weChats"
 *     responses:
 *       200:
 *         description: 签名获取成功
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 code:
 *                   type: integer
 *                   example: 200
 *                 message:
 *                   type: string
 *                   example: "签名获取成功"
 *                 data:
 *                   type: object
 *                   properties:
 *                     appId:
 *                       type: string
 *                       description: 微信公众号AppId
 *                     timestamp:
 *                       type: string
 *                       description: 时间戳
 *                     nonceStr:
 *                       type: string
 *                       description: 随机字符串
 *                     signature:
 *                       type: string
 *                       description: 签名
 *                     debugInfo:
 *                       type: object
 *                       description: 调试信息（开发环境可见）
 *       400:
 *         description: 参数错误
 *       500:
 *         description: 服务器内部错误
 */
router.post('/wechat/signature', async (req, res) => {
  try {
    const { url } = req.body;    
    // 验证参数
    if (!url) {
      return res.status(200).json({
        code: 400,
        message: 'URL参数不能为空'
      });
    }

    // 验证URL格式并规范化URL处理
    let normalizedUrl;
    try {
      const urlObj = new URL(url);
      
      // 规范化URL：保留协议、域名、路径和查询参数，但移除fragment(#后面部分)
      normalizedUrl = urlObj.origin + urlObj.pathname + (urlObj.search ? urlObj.search : '');
      
      // 特殊处理：确保URL格式一致性
      const hasExtension = /\.[^/.]+$/.test(urlObj.pathname);
      
      // 针对h5路径的特殊处理
      if (urlObj.pathname.startsWith('/h5') && !urlObj.pathname.includes('.')) {
        // h5路径确保以/结尾或包含参数
        if (!urlObj.pathname.endsWith('/') && !urlObj.search) {
          normalizedUrl = normalizedUrl + '/';
        }
      } else if (!urlObj.pathname.endsWith('/') && !hasExtension) {
        const alternativeUrl = normalizedUrl + '/';
      }      
    } catch (error) {
      return res.status(200).json({
        code: 400,
        message: 'URL格式不正确，请提供完整的URL（包含http/https）'
      });
    }

    // 检查是否为微信安全域名
    const securityDomain = 'www.stellargang.cn';
    const hasSecurityDomain = normalizedUrl.includes(securityDomain);
    
    // 检测常见的拼写错误
    const possibleMisspelledDomains = ['www.stelargang.cn'];
    let misspelledDomain = null;
    for (const domain of possibleMisspelledDomains) {
      if (normalizedUrl.includes(domain)) {
        misspelledDomain = domain;
        break;
      }
    }
    
    if (misspelledDomain) {
      return res.status(200).json({
        code: 400,
        message: `URL包含拼写错误的域名(${misspelledDomain})，正确的微信安全域名应为: ${securityDomain}`
      });
    }
    
    if (!hasSecurityDomain) {
      return res.status(200).json({
        code: 400,
        message: `URL必须在微信安全域名(${securityDomain})范围内`
      });
    }

    try {
      // 获取jsapi_ticket
      const ticket = await getJsapiTicket();
      
      // 生成签名所需参数
      const nonceStr = generateNonceStr();
      const timestamp = generateTimestamp();
      
      // 生成签名
      const signature = generateSignature(ticket, nonceStr, timestamp, normalizedUrl);      
      // 准备响应数据
      const responseData = {
        code: 200,
        message: '签名获取成功',
        data: {
          appId: wechatConfig.appId,
          timestamp: timestamp,
          nonceStr: nonceStr,
          signature: signature
        }
      };
      
      // 开发环境下添加调试信息
      if (process.env.NODE_ENV === 'development') {
        responseData.data.debugInfo = {
          url: normalizedUrl,
          signatureRaw: `jsapi_ticket=${ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${normalizedUrl}`,
          ticket: ticket.substring(0, 10) + '...', // 部分显示ticket，保护安全
          generatedAt: new Date().toISOString()
        };
      }
      
      // 返回签名信息
      res.json(responseData);      
    } catch (error) {
      // 具体错误处理
      if (error.message.includes('IP不在白名单中')) {
        return res.status(500).json({
          code: 500,
          message: '服务器IP不在微信公众号白名单中，请在微信公众平台添加IP白名单',
          error: process.env.NODE_ENV === 'development' ? error.message : '获取签名失败'
        });
      }
      
      res.status(500).json({
        code: 500,
        message: '服务器内部错误',
        error: process.env.NODE_ENV === 'development' ? error.message : '获取签名失败'
      });
    }

  } catch (error) {
    res.status(500).json({
      code: 500,
      message: '服务器内部错误',
      error: process.env.NODE_ENV === 'development' ? error.message : '获取签名失败'
    });
  }
});

module.exports = router;
